package shooter.maps;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;

/**
 * The GameMap is a component of the Mapeditor and loads maps.
 * 
 * @author Michail Tausch
 */
public class GameMap {
	
	int map[][];
	int spawn[][];
	MapCanvas mapCanvas;
	
	/**
	 * Constructor of this class. Calls the method helpConstructor.
	 * @param fileName
	 * @param rowCount
	 * @param mapCanvas
	 * @throws IOException
	 */
	public GameMap(String fileName, int rowCount, MapCanvas mapCanvas) throws IOException{
		this.mapCanvas = mapCanvas;
		File file = null;
		try {
			file = new File(ClassLoader.getSystemResource(fileName).toURI());
			this.helpConstructor(file, rowCount);
		} catch (URISyntaxException e) {
			throw new FileNotFoundException(e.getMessage());
		}
	}
	
	/**
	 * Constructor of this class. Calls the method helpConstructor.
	 * @param file
	 * @param rowCount
	 * @param mapCanvas
	 * @throws IOException
	 */
	public GameMap(File file, int rowCount, MapCanvas mapCanvas) throws IOException{
		this.mapCanvas = mapCanvas;
		this.helpConstructor(file, rowCount);
	}
	
	/**
	 * Reads a file and fills the map vector.
	 * @param file
	 * @param rowCount
	 * @throws IOException
	 */
	private void helpConstructor(File file, int rowCount) throws IOException{
		
		String map;
		
		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);

		String zahl = br.readLine();
		if (zahl.equals("1")) {
			rowCount = 20;
		} else if (zahl.equals("2")) {
			rowCount = 25;
		} else if (zahl.equals("3")) {
			 rowCount = 30;
		}
		
		spawn = new int [rowCount][rowCount];
		
		for(int x = 0; x < spawn.length; x++){
			for(int y = 0; y < spawn[x].length; y++){
				spawn[x][y]=0;
			}
		}

		this.map = new int[rowCount][rowCount];
		  
		String teamRot = br.readLine();
		for(int k = 0; k<Integer.parseInt(teamRot); k++){
			String tempRot = br.readLine();
			String[]coordinaten = tempRot.split("-");
			int x = Integer.parseInt(coordinaten[0]);
			int y = Integer.parseInt(coordinaten[1]);
			spawn[x][y]=8;
		}
		  
		String teamBlau = br.readLine();
		for(int k = 0; k<Integer.parseInt(teamBlau); k++){
			String tempBlau = br.readLine();
			String[]coordinaten = tempBlau.split("-");
			int x = Integer.parseInt(coordinaten[0]);
			int y = Integer.parseInt(coordinaten[1]);
			spawn[x][y]=9;
		}	

		map = readFileAsString(file);
		map = map.substring(map.indexOf(',') - 1);
		String[] mapLines = map.split(",");
		int[] gameMap = new int[mapLines.length];

		for (int i = 0; i < mapLines.length; i++) {
			mapLines[i] = mapLines[i].trim();
			gameMap[i] = Integer.parseInt(mapLines[i]);
		}
		this.map = flatToTabularArray(gameMap, rowCount);
	}
	
	/**
	 * Returns a two dimensional vector of the map.
	 * @param map
	 * @param rowCount
	 * @return
	 */
	public static int[][] flatToTabularArray(int[] map, int rowCount){
		int columnCount = map.length / rowCount;
		
		int[][] tabularMap = new int[columnCount][rowCount];
		
		for(int column = 0; column < columnCount; column++){
			for(int row = 0; row < rowCount; row++){
				tabularMap[column][row] = map[column + (row * columnCount)];
			}
		}		
		return tabularMap;
	}
	
	/**
	 * Returns the length of the map.
	 * @return
	 */
	public int getColumnCount(){
		return map.length;
	}

	/**
	 * Reads a file and returns it as a String
	 */
	public static String readFileAsString(File file) throws java.io.IOException{
        StringBuffer fileData = new StringBuffer(1000);
        BufferedReader reader = new BufferedReader(
                new FileReader(file));
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
        }
        reader.close();
        return fileData.toString();
    }
	
	/**
	 * Returns the value of the tile at a specific map position.
	 * @param column
	 * @param row
	 * @return
	 */
	public int getTileAt(int column, int row){
		return map[column][row];
	}
	
	/**
	 * Returns teh value of the tile at a specific column position.
	 * @param column
	 * @return
	 */
	public int[] getTileColumn(int column){
		return map[column];
	}
	
	/**
	 * Returns the map vector.
	 * @return
	 */
	public int[][] getIntArray(){
		return map;
	}
	
	/**
	 * Returns the spawn vector.
	 * @return
	 */
	public int[][] getSpawn() {
		return spawn;
	}	
}